#ifndef __OPS_H
#define __OPS_H

#include <stdint.h>

//#define FULL_PREC  //使用全精度开关，开启会导致更慢，更费RAM。不开启会有进位误差，测试最大误差为2

#define U16_BH(x) ((x)>>8)
#define U16_BL(x) ((x)&0xff)

#define U32_B0(x) ((x)&0xff)
#define U32_B1(x) (((x)>>8)&0xff)
#define U32_B2(x) (((x)>>16)&0xff)
#define U32_B3(x) ((x)>>24)

#define U8xU8_U16(a, b)    ((uint16_t)((a)*(b)))
#define U8xU8_RL8(a, b)    U16_BH((a)*(b))

#ifdef FULL_PREC
#define U16xU8_RL8(a, b)   (((uint32_t)(a)*(b))>>8)
#define I16xU8_RL8(a, b)   (((int32_t)(a)*(b))>>8)
#define U16xI8_RL8(a, b)   (((int32_t)(a)*(b))>>8)
#define U16xU16_RL16(a, b) (((uint32_t)(a)*(uint32_t)(b))>>16)
#define U16xI16_RL16(a, b) (((uint32_t)(a)*(int32_t)(b))>>16)
#else
#define U16xU8_RL8(a, b)   (U8xU8_U16(U16_BH(a), b) + U8xU8_RL8(U16_BL(a), b))
#define I16xU8_RL8(x, b)   (int8_t)U16xU8_RL8((uint16_t)x, b)
#define U16xI8_RL8(a, x)   ((int8_t)U16xU8_RL8(a, (uint8_t)x) - (x<0?U16_BL(a):0))
#define U16xU16_RL16(a, b) (U8xU8_U16(U16_BH(a), U16_BH(b)) + U8xU8_RL8(U16_BH(a), U16_BL(b)) + U8xU8_RL8(U16_BL(a), U16_BH(b)))
#define U16xI16_RL16(a, x) ((int16_t)U16xU16_RL16(a, (uint16_t)(x)) - (x<0?a:0))
#endif

#endif